

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>

#include "debug.h"
#include "ilist.h"
#include "token.h"


const char *INSTSTRING[] =
{
  "IS_NOP", 	     // = 0,
  "IS_READ",             // 1  read            -       -       out
  "IS_WRITE",            // 2  write           in      -       -
  "IS_ADD",              // 3  +               in      in      out
  "IS_SUB",              // 4  -               in      in      out
  "IS_MUL",              // 5  *               in      in      out
  "IS_DIV",              // 6  /               in      in      out
  "IS_GOTO",             // 7  goto if not 0   in      -       label   (in = NULL - skoc vzdy)
  "IS_LABEL",            // 8  label           label
  "IS_NOT",              // 9  negation        in      -       out     (in = 0 -> out = 1; in != 0 -> out = 0)
  "IS_COPY",             // 10 copy            in      -       out
  "IS_MOV",             // 10 copy            in      -       out
  "IS_LESS",             // 11 <               in      in      out     (out = 1 - pokud plati; 0 - pokud neplati)
  "IS_LESSEQ",           // 12 <=              in      in      out     (out = 1 - pokud plati; 0 - pokud neplati)
  "IS_GRT",              // 13 >               in      in      out     (out = 1 - pokud plati; 0 - pokud neplati)
  "IS_GRTEQ",            // 14 >=              in      in      out     (out = 1 - pokud plati; 0 - pokud neplati)
  "IS_EQUAL",            // 15 ==              in      in      out     (out = 1 - pokud plati; 0 - pokud neplati)

  "IS_LENGTH",           // 16 length()        in      -       out     (in = string, out = int)
  "IS_FIND",             // 17 find()          in      in      out     (in,in = string, out = int)
  "IS_SORT",             // 18 sort()          in      -       out     (in = string, out = string)
  "IS_CONCAT",           // 19 concat()        in      in      out     (in,in,out = string)
  "IS_GENVAR",
  "IS_CALL",               // 20 return          in      -       -
  "IS_PUSH",//22
  "IS_POP",//23
  "IS_RTN",               // 24 return          in      -       -
  "IS_FUNCT",               // 24 return          in      -       -
  "IS_CALLRTN",              // 24 return          in      -       -
  "IS_POWER",		   // mocnina
  "IS_NEQUAL"		   // !=
      "IS_TYPE",		   // !=
    "IS_SUBSTR"		   // !=
};

const char *TokenStr[]=
{
  "TOK_ID",      // identifikator
  "TOK_FUNC",        // funkce (pouze pro syntax. analyzu)
  "TOK_SEMI",       // ;
  "TOK_STRING",
  "TOK_DOUBLE",
  "TOK_COMMA",           // ,
  /*klicova slova:*/
  "TOK_MAIN",
  "TOK_DO",
  "TOK_ELSE",
  "TOK_END",
  "TOK_FALSE",
  "TOK_FUNCTION",
  "TOK_IF",
  "TOK_LOCAL",
  "TOK_NIL",
  "TOK_READ",
  "TOK_RETURN",
  "TOK_THEN",
  "TOK_TEST",
  "TOK_TRUE",
  "TOK_WHILE",
  "TOK_WRITE",

  "TOK_OTHERKEYWORDS",
  /*and, break, elseif, for, in, not, or, repeat, until    */
  //formaty pro read

  "TOK_PLUS",        // znamenko +
  "TOK_MINUS",           //          -
  "TOK_MULT",        //          *
  "TOK_DIV",          //          /
  "TOK_LESS",            //          <
  "TOK_LESSQ",          //          <=
  "TOK_GREAT",           //          >
  "TOK_GREATQ",         //          >=
  "TOK_EQ",           //          ==
  "TOK_NEQ",        //           ~=
  "TOK_ASSIGN",          //          =
  "TOK_POWER",          //          ^
  "TOK_CONCAT",          //          .. konkatenace

  "TOK_LBRACKET",     // (
  "TOK_RBRACKET",    // )



  "TOK_EOF",              // konec souboru
  "TOK_ILLEGAL",              // konec souboru
    "TOK_SUBSTR",
  "TOK_FIND",
  "TOK_SORT",
  "TOK_TYPE"
};

void _debug_printToken( TToken Token)
{
  printf("\n%s,%s",TokenStr[Token.Type],Token.pData);
}


void _debug_printHT( tHTable* ptrht )
{
  int maxlen = 0;
  int sumcnt = 0;

  printf ("------------HASH TABLE--------------\n");
  for ( int i=0; i<HTSIZE; i++ )
    {
      printf ("%i:",i);
      int cnt = 0;
      tHTItem* ptr = (*ptrht)[i];
      while ( ptr != NULL )
        {
          char *pole= (char *)malloc(8 * sizeof(char));
          switch(ptr->data.SymbolType)
            {
            case DOUBLE:
              pole="DOUBLE";
              break;
            case STRING:
              pole="STRING";
              break;
            case FUNCTI:
              pole="FUNCTI";
              break;
            case VARI:
              pole="VARI";
              break;
            case NIL:
              pole="NIL";
              break;
	    case UNDEF:
              pole="UNDEF";
              break;
            default:
              pole="NEVIM";
              break;
            }
          printf (" Key:'%s' ('%s','%s')\n",ptr->key,pole,ptr->data.pSymbolName);
          //if ( ptr != UNDEFPTR )
          cnt++;
          ptr = ptr->ptrnext;
        }
      printf ("\n");

      if (cnt > maxlen)
        maxlen = cnt;
      sumcnt+=cnt;
    }

  printf ("------------------------------------\n");
  printf ("Items count %i   The longest list %i\n",sumcnt,maxlen);
  printf ("------------------------------------\n");
}


void _debug(const char* fmt, ... )
{
#if defined (__WIN32__)
  va_list arg;
  fprintf( stdout, "[DEBUG]: ");
  va_start( arg, fmt );
  vfprintf( stdout, fmt, arg );
  va_end( arg );
  fprintf(stdout,"\n");
#else
  va_list arg;
  fprintf( stdout, "\033[00;32m[DEBUG]:\033[00m ");
  va_start( arg, fmt );
  vfprintf( stdout, fmt, arg );
  va_end( arg );
  fprintf(stdout,"\n");
#endif

}
void _debug_vamp(const char* fmt, ... )
{

#if defined (__WIN32__)
  va_list arg;
  va_start( arg, fmt );
  vfprintf( stdout, fmt, arg );
  va_end( arg );
#else
  va_list arg;
  va_start( arg, fmt );
  vfprintf( stdout, fmt, arg );
  va_end( arg );
#endif

}

void _warning(const char* fmt, ... )
{

#if defined (__WIN32__)
  va_list arg;
  fprintf( stdout, "[WARNING]: ");
  va_start( arg, fmt );
  vfprintf( stdout, fmt, arg );
  va_end( arg );
  fprintf(stdout,"\n");
#else
  va_list arg;
  fprintf( stdout, "\033[00;34m[WARNING]:\033[00m ");
  va_start( arg, fmt );
  vfprintf( stdout, fmt, arg );
  va_end( arg );
  fprintf(stdout,"\n");
#endif

}

void _error(const char* fmt, ... )
{

#if defined (__WIN32__)
  va_list arg;
  fprintf( stderr, "[ERROR]: ");
  va_start( arg, fmt );
  vfprintf( stderr, fmt, arg );
  va_end( arg );
  fprintf(stderr,"\n");
#else
  va_list arg;
  fprintf( stderr, "\033[00;31m[ERROR]:\033[00m ");
  va_start( arg, fmt );
  vfprintf( stderr, fmt, arg );
  va_end( arg );
  fprintf(stderr,"\n");
#endif

}

void _debug_instructions(tIList *L)
{

#if defined (__WIN32__)
  int i = 0;
  _debug("==== Start instruction dump ====");
  while(L->First!=NULL)
    {
      fprintf(stdout, "[INSTRUCTION %d]: (%s) 1:%s 2:%s 3:%s \n", ++i,INSTSTRING[L->First->Instr]+3,L->First->Addr1,L->First->Addr2,L->First->Addr3);
      L->First=L->First->pNext;

    }
  _debug("==== End instruction dump ====");
#else
  int i = 0;
  _debug("==== Start instruction dump ====");
  while(L->First!=NULL)
    {
      fprintf(stdout, "\033[00;33m[INSTRUCTION %d]\033[00m: (%s) 1:%s 2:%s 3:%s \n", ++i,INSTSTRING[L->First->Instr]+3,L->First->Addr1,L->First->Addr2,L->First->Addr3);
      L->First=L->First->pNext;

    }
  _debug("==== End instruction dump ====");
#endif


}
